﻿#pragma once

#include "MathCommon.h"
#include "Reflection/Reflection.h"
#include "Containers/String.h"
#include "Vec2.m.h"

RSTRUCT()
struct WHENGINE_API SVec2
{

	ROBJECT

	RFIELD()
	Float X;

	RFIELD()
	Float Y;

	SVec2()
	:X(0), Y(0)
	{}

	SVec2(float InX, float InY)
	:X(InX), Y(InY)
	{}

	SVec2& operator = (const SVec2& Other)
	{
		X = Other.X;
		Y = Other.Y;
		return *this;
	}

	SVec2 operator - () const
	{
		return SVec2(-X, -Y);
	}

	SVec2 operator + (const SVec2& Other) const
	{
		return SVec2(X + Other.X, Y + Other.Y);
	}

	SVec2 operator + (const Float& Other) const
	{
		return SVec2(X + Other, Y + Other);
	}

	SVec2& operator += (const SVec2& Other)
	{
		X += Other.X;
		Y += Other.Y;
		return *this;
	}

	SVec2& operator += (const Float& Other)
	{
		X += Other;
		Y += Other;
		return *this;
	}


	SVec2 operator - (const SVec2& Other) const
	{
		return SVec2(X - Other.X, Y - Other.Y);
	}
	SVec2& operator -= (const SVec2& Other)
	{
		X -= Other.X;
		Y -= Other.Y;
		return *this;
	}

	SVec2 operator * (const SVec2& Other) const
	{
		return SVec2(X * Other.X, Y * Other.Y);
	}
	SVec2& operator *= (const SVec2& Other)
	{
		X *= Other.X;
		Y *= Other.Y;
		return *this;
	}

	SVec2 operator / (const SVec2& Other) const
	{
		return SVec2(X / Other.X, Y / Other.Y);
	}
	SVec2& operator /= (const SVec2& Other)
	{
		X /= Other.X;
		Y /= Other.Y;
		return *this;
	}

	SVec2 operator - (const Float& Other) const
	{
		return SVec2(X - Other, Y - Other);
	}


	SVec2& operator -= (const Float& Other)
	{
		X -= Other;
		Y -= Other;
		return *this;
	}

	SVec2 operator * (const Float& Other) const
	{
		return SVec2(X * Other, Y * Other);
	}

	SVec2& operator *= (const Float& Other)
	{
		X *= Other;
		Y *= Other;
		return *this;
	}

	SVec2 operator / (const Float& Other) const
	{
		return SVec2(X / Other, Y / Other);
	}

	SVec2& operator /= (const Float& Other)
	{
		X /= Other;
		Y /= Other;
		return *this;
	}

	bool operator == (const SVec2& Other) const
	{
		return X == Other.X && Y == Other.Y;
	}

	bool operator != (const SVec2& Other) const
	{
		return X != Other.X || Y != Other.Y;
	}

	Float DotProduct(const SVec2& Other) const
	{
		return X * Other.X + Y * Other.Y;
	}

	Float CrossProduct(const SVec2& Other) const;

	Float GetLength();

	//获取X、Y中的最大值
	Float GetMax() const;

	void Normalize();

	SVec2 ToNormalized();

	void ToFloatArray(float OutArray[2]) const;
};

namespace WH
{
	WHENGINE_API CString ToString(const SVec2& InValue);
}